﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using PayPal.PayPalAPIInterfaceService;
using PayPal.PayPalAPIInterfaceService.Model;

namespace PayPalPay.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        private string _ReturnUrl;
        private string ReturnUrl
        {
            get
            {
                if (_ReturnUrl == null)
                {
                    string schemeHost = HttpContext.Request.Url.GetLeftPart(UriPartial.Authority);
                    //
                    _ReturnUrl = schemeHost + "/" + ServiceConfig["ReturnUrl"];
                }
                return _ReturnUrl;
            }
        }

        private string _CancelUrl;
        private string CancelUrl
        {
            get
            {
                if (_CancelUrl == null)
                {
                    string schemeHost = HttpContext.Request.Url.GetLeftPart(UriPartial.Authority);
                    //
                    _CancelUrl = schemeHost + "/" + ServiceConfig["CancelUrl"];
                }
                return _CancelUrl;
            }
        }

        private string _LogoUrl;
        private string LogoUrl
        {
            get
            {
                if (_LogoUrl == null)
                {
                    string schemeHost = HttpContext.Request.Url.GetLeftPart(UriPartial.Authority);
                    //
                    _LogoUrl = schemeHost + "/" + ServiceConfig["LogoUrl"];
                }
                return _LogoUrl;
            }
        }

        private string _SellerEmail;
        private string SellerEmail
        {
            get
            {
                if (_SellerEmail == null)
                {
                    _SellerEmail = ServiceConfig["SellerEmail"];
                }
                return _SellerEmail;
            }
        }

        private string _RedirectUrl;
        private string RedirectUrl
        {
            get
            {
                if (_RedirectUrl == null)
                {
                    _RedirectUrl = ServiceConfig["RedirectUrl"];
                }
                return _RedirectUrl;
            }
        }


        private Dictionary<string, string> _ServiceConfig;
        private Dictionary<string, string> ServiceConfig
        {
            get
            {
                if (_ServiceConfig == null)
                {
                    //从配置文件加载配置
                    _ServiceConfig = PayPal.Manager.ConfigManager.Instance.GetProperties();
                    //或直接赋值
                    //Dictionary<string, string> sdkConfig = new Dictionary<string, string>();
                    //sdkConfig.Add("mode", "sandbox");
                    //sdkConfig.Add("account1.apiUsername", "jb-us-seller_api1.paypal.com");
                    //sdkConfig.Add("account1.apiPassword", "WX4WTU3S8MY44S7F");
                    //sdkConfig.Add("account1.apiSignature", "AFcWxV21C7fd0v3bYYYRCpSSRl31A7yDhhsPUU2XhtMoZXsWHFxu-RWy");
                }
                return _ServiceConfig;
            }
        }

        private PayPalAPIInterfaceServiceService _PayService;
        private PayPalAPIInterfaceServiceService PayService
        {
            get
            {
                if (_PayService == null)
                {
                    //从配置文件加载配置
                    Dictionary<string, string> config = PayPal.Manager.ConfigManager.Instance.GetProperties();

                    _PayService = new PayPalAPIInterfaceServiceService(config);
                }
                return _PayService;
            }
        }

        private SetExpressCheckoutResponseType SetExpressCheckout(PayPalAPIInterfaceServiceService sservice)
        {
            //
            SetExpressCheckoutResponseType response = sservice.SetExpressCheckout(new SetExpressCheckoutReq()
                  {
                      SetExpressCheckoutRequest = new SetExpressCheckoutRequestType()
                      {
                          Version = "104.0",
                          SetExpressCheckoutRequestDetails = new SetExpressCheckoutRequestDetailsType()
                          {
                              //ReturnURL = "",
                              //CancelURL = "",
                              PaymentDetails = new List<PaymentDetailsType>() { 
                                   new PaymentDetailsType()
                                   {
                                       PaymentAction = PaymentActionCodeType.SALE,
                                       OrderTotal = new BasicAmountType(CurrencyCodeType.USD, "1"),
                               
                                       PaymentDetailsItem=new List<PaymentDetailsItemType>(){
                                           new PaymentDetailsItemType()
                                           {
                                                Name="This Is A Book",
                                                Quantity = 1,
                                                Amount = new BasicAmountType(CurrencyCodeType.USD, "1"),
                                                ItemCategory = ItemCategoryType.PHYSICAL                                     
                                           }
                                       }
                                   }
                               }
                          }
                      }
                  });

            return response;
        }

        private GetExpressCheckoutDetailsResponseType GetExpressCheckout(PayPalAPIInterfaceServiceService sservice, string token)
        {
            GetExpressCheckoutDetailsResponseType response = sservice.GetExpressCheckoutDetails(new GetExpressCheckoutDetailsReq()
               {
                   GetExpressCheckoutDetailsRequest = new GetExpressCheckoutDetailsRequestType()
                   {
                       Token = token,
                       Version = "11.0"
                   }
               });
            return response;
        }

        public ActionResult GetExpressCheckoutDetails()
        {
            string payerid = Request.QueryString.Get("PayerId");
            string token = Request.QueryString.Get("Token");

            PayPalAPIInterfaceServiceService services = PayService;

            GetExpressCheckoutDetailsResponseType getdtlResponse = services.GetExpressCheckoutDetails(new GetExpressCheckoutDetailsReq()
                  {
                      GetExpressCheckoutDetailsRequest = new GetExpressCheckoutDetailsRequestType()
                      {
                          Token = token,
                          Version = "104.0"
                      }
                  });
            if (getdtlResponse.Ack == AckCodeType.SUCCESS || getdtlResponse.Ack == AckCodeType.SUCCESSWITHWARNING)
            {
                string payerid2 = getdtlResponse.GetExpressCheckoutDetailsResponseDetails.PayerInfo.PayerID;
                List<PaymentDetailsType> paymentDetails = getdtlResponse.GetExpressCheckoutDetailsResponseDetails.PaymentDetails.ToList();
                SellerDetailsType seller = new SellerDetailsType()
                {
                    PayPalAccountID = SellerEmail
                };
                paymentDetails.ForEach(model => model.SellerDetails = seller);

                DoExpressCheckoutPaymentResponseType payResponse = services.DoExpressCheckoutPayment(
                    new DoExpressCheckoutPaymentReq()
                    {
                        DoExpressCheckoutPaymentRequest = new DoExpressCheckoutPaymentRequestType()
                        {
                            Version = "104.0",
                            DoExpressCheckoutPaymentRequestDetails = new DoExpressCheckoutPaymentRequestDetailsType()
                            {
                                Token = token,
                                PayerID = payerid2,
                                PaymentAction = PaymentActionCodeType.SALE,
                                PaymentDetails = paymentDetails
                            }
                        }
                    });
                //
                if (payResponse.Ack == AckCodeType.SUCCESS || payResponse.Ack == AckCodeType.SUCCESSWITHWARNING)
                {
                    payResponse.DoExpressCheckoutPaymentResponseDetails.PaymentInfo.ForEach(paymentinfo => {
                        ViewBag.Message += "TransactionID:" + paymentinfo.TransactionID + Environment.NewLine
                            + "PaymentDate:" + paymentinfo.PaymentDate + Environment.NewLine
                            + (paymentinfo.TransactionType.HasValue ? "TransactionType:" + paymentinfo.TransactionType.Value.ToString() + Environment.NewLine : "")
                            + (paymentinfo.PaymentStatus.HasValue ? "PaymentStatus:" + paymentinfo.PaymentStatus.Value.ToString() + Environment.NewLine : "")
                            + (paymentinfo.PaymentType.HasValue ? "PaymentType:" + paymentinfo.PaymentType.Value.ToString() : "")
                            ;
                    });
                }
                else
                {
                    payResponse.Errors.ForEach(errortype => {
                        ViewBag.Message += "ErrorCode:" + errortype.ErrorCode + Environment.NewLine
                            + "ShortMessage:" + errortype.ShortMessage + Environment.NewLine
                            + "LongMessage:" + errortype.LongMessage + Environment.NewLine;
                    });
                }
            }
            else
            {
                getdtlResponse.Errors.ForEach(errortype =>
                {
                    ViewBag.Message += "ErrorCode:" + errortype.ErrorCode + Environment.NewLine
                        + "ShortMessage:" + errortype.ShortMessage + Environment.NewLine
                        + "LongMessage:" + errortype.LongMessage + Environment.NewLine;
                });
            }

            return View();
        }

        [HttpPost]
        public ActionResult Submit(FormCollection collection)
        {
            string goodsname = collection.Get("GoodsName");
            string price = collection.Get("GoodsPrice");
            string currency = collection.Get("Currency");
            string quantity = collection.Get("Quantity");
            //
            string schemeHost = HttpContext.Request.Url.GetLeftPart(UriPartial.Authority);
            //
            string returnUrl = schemeHost + "/" + ServiceConfig["ReturnUrl"];
            string cancelUrl = schemeHost + "/" + ServiceConfig["CancelUrl"];
            string redirectUrl = ServiceConfig["RedirectUrl"];
            //
            int nums;
            if (Int32.TryParse(quantity, out nums) == false)
                nums = 1;
            //
            CurrencyCodeType currencycode;
            if (!Enum.TryParse<CurrencyCodeType>(currency, out currencycode))
                currencycode = CurrencyCodeType.USD;

            PayPalAPIInterfaceServiceService sservice = PayService;
            System.Text.StringBuilder sbErrMsg = new System.Text.StringBuilder();
            //
            SetExpressCheckoutResponseType response = sservice.SetExpressCheckout(new SetExpressCheckoutReq()
            {
                SetExpressCheckoutRequest = new SetExpressCheckoutRequestType()
                {
                    Version = "104.0",
                    SetExpressCheckoutRequestDetails = new SetExpressCheckoutRequestDetailsType()
                    {
                        ReturnURL = returnUrl, //"http://localhost:5097/Home/GetExpressCheckoutDetails",
                        CancelURL = cancelUrl, //"http://localhost:5097/Home/Contact",
                        PaymentDetails = new List<PaymentDetailsType>() { 
                                   new PaymentDetailsType()
                                   {
                                       PaymentAction = PaymentActionCodeType.SALE,
                                       OrderTotal = new BasicAmountType(CurrencyCodeType.USD, (Convert.ToInt32(price)*nums).ToString()),
                               
                                       PaymentDetailsItem=new List<PaymentDetailsItemType>(){
                                           new PaymentDetailsItemType()
                                           {
                                                Name="This Is A Book",
                                                Quantity = nums,
                                                Amount = new BasicAmountType(currencycode, price),
                                                ItemCategory = ItemCategoryType.PHYSICAL                                     
                                           }
                                       }
                                   }
                               }
                    }
                }
            });

            if (response.Ack == AckCodeType.SUCCESS || response.Ack == AckCodeType.SUCCESSWITHWARNING)
            {
                return Redirect(redirectUrl + HttpUtility.UrlEncode(response.Token));
                //
            }
            else
            {
                response.Errors.ForEach(error =>
                {
                    sbErrMsg.AppendFormat("ErrorCode:{0}\r\nShortMessage:{1}\r\nLongMessage:{2}\r\n", error.ErrorCode, error.ShortMessage, error.LongMessage);
                });

                ViewBag.Message = sbErrMsg.ToString();
                return View("About");
            }
        }

        public ActionResult About()
        {
            ViewBag.Message = "Your application description page.";

            return View();
        }

        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";

            return View();
        }
    }
}